import {VirtualLoopData} from '../../models/svgdata';
import {drawConfigType, drawPropsType, BaseDrawConfig} from '../types/draw-config.type';
import {OutputList, InputList} from '../../models/svgdata'
import '@svgdotjs/svg.panzoom.js';
import Konva from 'konva';
import {G} from '@svgdotjs/svg.js';


interface sizeType {
  width: number,
  height: number
}

const drawDefaultConfig: drawConfigType = {
  baseDrawConfig: {
    moduleDistance: 700,
    font: {
      small: 8,
      normal: 11,
    },
    color: {
      primary: '#00367a',
      moduleBorderColor: '#25ccf7',
      accent: '#25ccf7',
      text: '#ffffff',
      dashedLine: '#000000',
    }
  },
  loopBranchConfig: {
    lineColor: '#25ccf7',
    textColor: '#ffffff',
    textSize: 8,
    lineDistance: 700,
  }
}


export function konvaRender(stage: Konva.Stage, data: VirtualLoopData, canvasSize: sizeType, moduleSize: sizeType, drawPropsType: drawPropsType) {
  const drawConfig = drawPropsType.drawConfig || drawDefaultConfig
  let layer = new Konva.Layer();
  const drawGroup = new Konva.Group({
    x: (stage.width() - canvasSize.width)/2,
    y: (stage.height() - canvasSize.height)/2,
    draggable: true,
  });
  const group = new Konva.Group({
    x: (canvasSize.width - moduleSize.width - drawConfig.baseDrawConfig.moduleDistance)/2,
    y: (canvasSize.height - moduleSize.height)/2,
  })
  const drawRect = new Konva.Rect({
    width: canvasSize.width,
    height: canvasSize.height,
    fill: '#070a0a',
  })

  drawGroup.add(drawRect);
  drawGroup.add(group);
  layer.add(drawGroup);
  stage.add(layer);

  let elementHeight = 25

  const leftGroup = new Konva.Group()
  const leftGroupRect = new Konva.Rect({
    width: moduleSize.width,
    height: moduleSize.height,
    fill: drawConfig.baseDrawConfig.color.primary,
    stroke: drawConfig.baseDrawConfig.color.moduleBorderColor,
    strokeWidth: 0.5,
  })
  leftGroup.add(leftGroupRect);
  const rightGroup = new Konva.Group({
    x: drawConfig.baseDrawConfig.moduleDistance,
    y: 0,
  })
  const rightGroupRect = new Konva.Rect({
    width: moduleSize.width,
    height: moduleSize.height,
    fill: drawConfig.baseDrawConfig.color.primary,
    stroke: drawConfig.baseDrawConfig.color.moduleBorderColor,
    strokeWidth: 0.5,
  })
  rightGroup.add(rightGroupRect);

  group.add(leftGroup);
  group.add(rightGroup);


  leftGroup.add(new Konva.Text({
    text: data.connectionData[0].noCentreIed.name,
    y: elementHeight,
    width: moduleSize.width,
    fill: drawConfig.baseDrawConfig.color.text,
    fontSize: drawConfig.baseDrawConfig.font.normal,
    align: 'center',
  }));

  rightGroup.add(new Konva.Text({
    text: data.centreIed.name,
    y: elementHeight,
    width: moduleSize.width,
    fill: drawConfig.baseDrawConfig.color.text,
    fontSize: drawConfig.baseDrawConfig.font.normal,
    align: 'center',
  }));

  elementHeight += 15;

  leftGroup.add(new Konva.Text({
    text: splitTextByLineLength(data.connectionData[0].noCentreIed.desc),
    y: elementHeight,
    width: moduleSize.width,
    fill: drawConfig.baseDrawConfig.color.text,
    fontSize: drawConfig.baseDrawConfig.font.normal,
    align: 'center',
  }));

  rightGroup.add(new Konva.Text({
    text: splitTextByLineLength(data.centreIed.desc),
    y: elementHeight,
    width: moduleSize.width,
    fill: drawConfig.baseDrawConfig.color.text,
    fontSize: drawConfig.baseDrawConfig.font.normal,
    align: 'center',
  }));

  elementHeight += 60;

  for(let outputItem of data.connectionData[0].outputList){
    elementHeight = konvaRenderVirtualLoop(stage, group, elementHeight, outputItem, {x: 750, y: 0}, 'output') + 40
  }

  for(let inputItem of data.connectionData[0].inputList){
    elementHeight = konvaRenderVirtualLoop(stage, group, elementHeight, inputItem, {x: 750, y: 0}, 'input') + 40
  }

}

export function splitTextByLineLength(text: string, maxCharsPerLine: number = 19) {
  if (!text || maxCharsPerLine <= 0) return text || '';
  const lines = [];
  let start = 0;
  const len = text.length;
  while (start < len) {
    let slice = text.slice(start, start + maxCharsPerLine);
    if (start + maxCharsPerLine < len && text[start + maxCharsPerLine] !== ' ' && slice.includes(' ')) {
      const lastSpaceIdx = slice.lastIndexOf(' ');
      if (lastSpaceIdx > 0) {
        slice = slice.slice(0, lastSpaceIdx);
      }
    }
    lines.push(slice.trim());
    start += slice.length;
  }
  return lines.join('\n');
}


export function konvaRenderVirtualLoop(stage: Konva.Stage, group: Konva.Group, elementHeight: number, messageContent: InputList | OutputList, rightPoint: {x: number, y: number}, type: 'output' | 'input') {
  const loopGroup = new Konva.Group({
    x: 70,
    y: elementHeight,
  });
  loopGroup.add(new Konva.Circle({
    x: type === 'output' ? 0 : 780,
    radius: 8,
    fill: '#25ccf7'
  }))
  loopGroup.add(new Konva.Rect({
    x: type === 'output' ? 780 :-60,
    y: -10,
    width: 60,
    height: 20,
    fill: '#25ccf7'
  }))
  loopGroup.add(new Konva.Text({
    text:'GOOSE '+ messageContent.appid16,
    x: type === 'output' ? 780 :-60,
    y: -2,
    width: 60,
    height: 20,
    align: 'center',
    fontSize: 8,
  }))
  loopGroup.add(new Konva.Line({
    points: [0, 0, 780, 0],
    stroke: '#25ccf7',
    strokeWidth: 2,
  }))

  loopGroup.add(new Konva.Rect({
    x: 16,
    y: -11,
    width: 20,
    height: 10,
    fill: '#0985d9',
  }))

  // 创建切换文字元素
  const toggleText = new Konva.Text({
    text: '展开',
    x: 16,
    y: -8,
    width: 20,
    align: 'center',
    fontSize: 8,
  });
  loopGroup.add(toggleText);

  const branchGroup = new Konva.Group({});
  elementHeight += konvaRenderLoopBranch(branchGroup, messageContent);
  loopGroup.add(branchGroup);

  const arrowGroup = konvaRenderArrow(8, '#25ccf7', branchGroup, toggleText).position({
    x: type === 'output' ? 280 :400,
    y: 0,
  })
  type === 'output' && arrowGroup.rotation(180);
  loopGroup.add(arrowGroup)

  group.add(loopGroup);

  return elementHeight;
}

export function konvaRenderLoopBranch(branchGroup: Konva.Group, messageContent: InputList | OutputList){
  let height = 20;
  for(let item of messageContent.enaTerminalList) {
    let pathData = '';
    let SoftStrapGroup: Konva.Group | undefined;
    const hasSwitch = !!item.ena
    if(item.terminalList.length > 1){
      pathData += `M750 0 l0 ${height + 20 * (item.terminalList.length - 1)/2} l-152 0`;
      if(hasSwitch){
        SoftStrapGroup = konvaRenderSoftStrap(branchGroup, item.ena.outputEnaDesc, 635, height+ 20 * (item.terminalList.length - 1)/2)
      }
      const endX = 750 - 152
      const endY = height+ 20 * (item.terminalList.length - 1)/2
      for(let branch of item.terminalList) {
        pathData += `M${endX} ${endY} l0 ${height - endY} l-572 0 l0 -20`;
        branchGroup.add(new Konva.Text({
          text: hasSwitch ? item.terminalList[0].inputDesc : item.terminalList[0].outputDesc,
          x: 180,
          y: height - 10,
          fontSize: 8,
          fill: '#fff'
        }))
        branchGroup.add(new Konva.Text({
          text: hasSwitch ? item.terminalList[0].outputDesc : item.terminalList[0].inputDesc,
          x: 420,
          y: height - 10,
          width: 160,
          fontSize: 8,
          fill: '#fff',
          align: 'right'
        }))
        height += 20
      }
    }else if(item.terminalList.length === 1){
      pathData += `M750 0 l0 ${height} l-724 0 l0 -20`;
      if(hasSwitch){
        SoftStrapGroup = konvaRenderSoftStrap(branchGroup, item.ena.outputEnaDesc, 635, height)
      }
      branchGroup.add(new Konva.Text({
        text: hasSwitch ? item.terminalList[0].inputDesc : item.terminalList[0].outputDesc,
        x: 180,
        y: height - 10,
        fontSize: 8,
        fill: '#fff'
      }))
      branchGroup.add(new Konva.Text({
        text: hasSwitch ? item.terminalList[0].outputDesc : item.terminalList[0].inputDesc,
        x: 420,
        y: height - 10,
        fontSize: 8,
        width: 160,
        fill: '#fff',
        align: 'right'
      }))
      height += 20
    }
    branchGroup.add(new Konva.Path({
      data: pathData,
      fill: 'transparent',
      stroke: '#25ccf7',
      strokeWidth: 1
    }))

    if (SoftStrapGroup) {
      branchGroup.add(SoftStrapGroup);
    }
  }

  return height
  // return elementHeight + height - 20
}


export function konvaRenderSoftStrap(branchGroup: Konva.Group, desc: string, x: number, y: number){
  const softStrapGroup = new Konva.Group({
    x: x,
    y: y-4,
  })

  const buttonGroup = new Konva.Group({
    x: (110-24)/2
  })

  buttonGroup.add(new Konva.Rect({
    width: 24,
    height: 8,
    cornerRadius: 4,
    fill: '#bdf4f1',
  }))
  buttonGroup.add(new Konva.Circle({
    radius: 4,
    x: 4,
    y: 4,
    fill: 'white',
  }))
  buttonGroup.add(new Konva.Circle({
    radius: 4,
    x: 20,
    y: 4,
    fill: 'white',
  }))
  softStrapGroup.add(new Konva.Text({
    text: desc,
    y: 10,
    width: 110,
    height: 24,
    align: 'center',
    fontSize: 8,
    fill: '#fff'
  }))

  softStrapGroup.add(buttonGroup)

  return softStrapGroup
}

export function konvaRenderArrow(size: number = 8, color: string = '#25ccf7', branchGroup?: Konva.Group, toggleText?: Konva.Text) {
  const arrowGroup  = new Konva.Group();
  const pathData = `M0 $0 l-${size * 2} -${size} l${size} ${size} l-${size} ${size} Z`;
  arrowGroup.add(new Konva.Rect({
    width: size * 2,
    height: size * 2,
  }))
  arrowGroup.add(new Konva.Path({
    data: pathData,
    fill: color,
  }))
  arrowGroup.on('mouseover', function (e) {
    e.target.getStage()!.container().style.cursor = 'pointer';
  });
  arrowGroup.on('mouseout', function (e) {
    e.target.getStage()!.container().style.cursor = 'default';
  });
  arrowGroup.on('click', () => {
    if (branchGroup && toggleText) {
      const isVisible = branchGroup.visible();
      branchGroup.visible(!isVisible);

      toggleText.text(isVisible ? '展开' : '收起');

      arrowGroup.getLayer()?.batchDraw();
    }
  })
  return arrowGroup
}
